%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ST.h"
#define YYDEBUG 1
int errors;

void install (char *sym_name)
{
	symrec *s;
	s = getsym(sym_name);
	if (!s)
		s = putsym(sym_name);
	else {
		errors++;
		fprintf(stderr, "%s is already defined\n", sym_name);
	}
}

void context_check (char *sym_name)
{
	if(!getsym(sym_name)) {
		errors++;
		fprintf(stderr, "%s is an undeclared indetifier\n", sym_name);
	}
}
%}

%union {
	char *id;
}

%start program
%token INT SKIP IF THEN ELSE FI WHILE END
%token DO INTEGER READ WRITE LET IN
%token ASSGNOP
%token <id> IDENT
%left '-' '+'
%left '*' '/'
%right '^'

%%

program: LET declarations IN commands END
			 ;
declarations: /* empty */
						| INTEGER id_seq IDENTIFIER ',' { install($3); }
						;
id_seq: /* empty */
			| id_seq IDENTIFIER ',' { install($2); }
			;

commands: /* empty */
				| commands command ';'
				;

command: SKIP
			 | READ INDENTIFIER 	{ context_check(READ_INT, $2); }
			 | WRITE exp
			 | IDENTIFIER ASSGNOP exp { context_check(STORE, $1); }
			 | IF exp THEN commands ELSE commands FI
			 | WHILE exp DO commands END
			 ;
exp: NUMBER
	 | IDENTIFIER { context_check(LD_VAR, $1); }
	 | exp '<' exp
	 | exp '=' exp
	 | exp '>' exp
	 | exp '+' exp
	 | exp '-' exp
	 | exp '*' exp
	 | exp '/' exp
	 | exp '^' exp
	 | '(' exp ')'
	 ;

%%

int main (int argc, char* argv[])
{
	extern FILE *yyin;
	++argv; --argc;
	yyin = fopen(argv[0], "r");
	errors = 0;
	yyparse();
	printf("Parse Completed\n");
	return 0;
}

void yyerror (char *s)
{
	errors++;
	fprintf(stderr, "%s\n", s);
}
